﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace TCG
{
    /// <summary>
    /// 常用工具方法
    /// </summary>

    public static class CommonTools 
    {
		public static string StreamingDirNameBase = "StreamingAssets";

		#if UNITY_IPHONE
		public static string StreamingDirName = StreamingDirNameBase + "_IOS";
		#elif UNITY_ANDROID
		public static string StreamingDirName = StreamingDirNameBase + "_Android";
		#else
		public static string StreamingDirName = StreamingDirNameBase;
		#endif

        /// <summary>
        /// 存储打包后文件的顶级目录的运行时完整路径
        /// </summary>

        public static string GetStreamingDirPath ()
        {
            #if UNITY_EDITOR
            return Path.Combine (Application.dataPath, StreamingDirName);

            #else
			return Path.Combine (Application.persistentDataPath, StreamingDirName ());
            #endif
        }

        /// <summary>
        /// 工程发布后，存放打包后文件的目录在目标平台上的路径，一般来说，这个目录位于应用包内部，
        /// 是不能被直接更新、修改的，在应用启动时，应该将该路径下的所有资源同步到
        /// GetStreamingDirPath返回的目录中
        /// </summary>

        public static string GetStreamingDirPathInBuild ()
        {
            #if UNITY_IPHONE
            return Path.Combine (Application.dataPath + "/../", StreamingDirName);

            #elif UNITY_ANDROID
            // TODO 安卓平台的目录到底在哪儿？
            return null;

			#else
			return null;
            #endif
        }

        #if UNITY_EDITOR
        /// <summary>
        /// 存储打包后文件的顶级目录相对于Unity工程目录的路径.
        /// </summary>

        public static string GetStreamingDirPathInUnity ()
        {
            return "Assets/" + StreamingDirName;
        }
        #endif

        /// <summary>
        /// 返回运行时处于资源包顶级目录中<paramref name="relativePath"/>处资源的完整路径.
        /// </summary>

        public static string GetStreamingPath (string relativePath)
        {
			string result = Path.Combine (GetStreamingDirPath (), relativePath);
#if UNITY_EDITOR
			FileInfo fi = new FileInfo (result);
			if (!fi.Directory.Exists)
			{
				fi.Directory.Create ();
			}
#endif
            return result;
        }

        /// <summary>
        /// 返回运行时位于程序包中的资源顶级目录中<paramref name="relativePath"/>处资源的完整路径.
        /// </summary>

        public static string GetStreamingPathinBuild (string relativePath)
        {
            return Path.Combine (GetStreamingDirPathInBuild (), relativePath);
        }

        #if UNITY_EDITOR
        /// <summary>
        /// 返回位于资源顶级目录中<paramref name="relativePath"/>处的资源在编辑器中相对于Unity工程目录的路径.
        /// </summary>

        public static string GetStreamingPathInUnity (string relativePath)
        {
            return Path.Combine (GetStreamingDirPathInUnity (), relativePath);
        }
        #endif


        /// <summary>
        /// 将集合<paramref name="collection"/>序列化到字符串中并返回，<paramref name="seperator"/>
        /// 用来控制序列化时每个元素的分隔符，集合中的每个元素在序列化时会被调用其定义的ToString ()方法。
        /// </summary>

        public static string JointCollection<T> (IEnumerable<T> collection, string seperator = ",")
        {
			if (collection == null) return string.Empty;

            StringBuilder sb = new StringBuilder();
            foreach (T element in collection)
            {
                sb.Append (element.ToString());
                sb.Append (seperator);
            }
            // 删除最后的分割符
            if (sb.Length > 0)
            {
                sb.Remove (sb.Length - 1, 1);
            }
            return sb.ToString ();
        }


        /// <summary>
        /// 将<paramref name="sourcePath"/>文件夹下的所有内容递归复制到文件夹
        /// <paramref name="destPath"/>中
        /// </summary>

        public static void CopyDirectory (string sourcePath, string destPath)
        {
            DirectoryInfo info = new DirectoryInfo (sourcePath);
            if (!Directory.Exists (destPath))
            {
                Directory.CreateDirectory (destPath);
            }

            foreach (FileSystemInfo fsi in info.GetFileSystemInfos ())
            {
                string destName = Path.Combine (destPath, fsi.Name);

                if (fsi is System.IO.FileInfo)
                {
                    File.Copy (fsi.FullName, destName, true);
                }
                else
                {
                    CopyDirectory (fsi.FullName, destName);
                }
            }

        }

        /// <summary>
        /// 获取对象<paramref name="go"/>上类型为<paramref name="T"/>的组件，如不存在，则
        /// 附加后返回。
        /// </summary>

        public static T CheckComponent<T> (GameObject go) where T:Component
        {
            T component = go.GetComponent<T> ();
            if (component == null)
            {
                component = go.AddComponent<T> ();
            }
            return component;
        }

		/// <summary>
		/// 从资源名称中解析其ID，资源名称必须按照{id}_{name}的形式命名.
		/// </summary>

		public static uint ParseAssetIdFromName (string assetName)
		{
			System.Text.RegularExpressions.Regex pattern = new System.Text.RegularExpressions.Regex (@"^\d+");
			System.Text.RegularExpressions.Match match = pattern.Match (assetName);
			if (match.Success)
			{
				return uint.Parse (match.Value);
			}
			else
			{
				throw new System.Exception (string.Format ("资源{0}名称有误，请遵循{{id}}_{{name}}命名规范", assetName));
			}
		}

		/// <summary>
		/// 将vector3格式化为x,y,z的形式.
		/// </summary>

		public static string JointVector3 (Vector3 vec)
		{
			return string.Format ("{0},{1},{2}", vec.x, vec.y, vec.z);
		}

		/// <summary>
		/// 将x,y,z格式的字符串解析成vector3.
		/// </summary>

		public static Vector3 JointValueToVector3 (string strVector3)
		{
			string[] vecComps = strVector3.Split (',');
			return new Vector3 (
				float.Parse (vecComps[0]), float.Parse (vecComps[1]), float.Parse (vecComps[2]));
		}

		/// <summary>
		/// 将vector4格式化为x,y,z,w的形式.
		/// </summary>

		public static string Vector4ToJointValue (Vector4 vec)
		{
			return string.Format ("{0},{1},{2},{3}", vec.x, vec.y, vec.z, vec.w);
		}

		/// <summary>
		/// 将x,y,z,w格式的字符串解析成vector4.
		/// </summary>

		public static Vector4 JointValueToVector4 (string strVector4)
		{
			string[] vecComps = strVector4.Split (',');
			return new Vector4 (
				float.Parse (vecComps[0]), float.Parse (vecComps[1]), float.Parse (vecComps[2]), float.Parse (vecComps[3]));
		}
    }
}